package cn.xiuxius.embedded.command.flash;

import cn.xiuxius.embedded.model.FlashOptionType;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;

@Accessors(chain = true)
@Setter
public class FlashOptionWrapper {

    @Getter
    private String name;
    @Getter
    private String flag;
    @Getter
    private FlashOptionType<?> value;
    @Getter
    private String description;
    @Getter
    private boolean isAdvanced = false;
    @Getter
    private Predicate<FlashOptionWrapper> isDefaultValue = defaultCheck;

    @Getter
    private boolean onlyFlag = false;

    public static Predicate<FlashOptionWrapper> defaultCheck = new Predicate<FlashOptionWrapper>() {
        @Override
        public boolean test(FlashOptionWrapper flashOptionWrapper) {
            return flashOptionWrapper.getValue().isDefault();
        }
    };

    public FlashOptionWrapper setValue(FlashOptionType<?> v) {
        if (v != null) {
            this.value = v;
        }
        return this;
    }

    public static List<String> toCommand(List<FlashOptionWrapper> options) {
        List<String> commands = new ArrayList<>();
        for (FlashOptionWrapper option : options) {
            if (option.isAdvanced && !ALLOWED_ADVANCED_OPTIONS.contains(option.getName())) {
                continue;
            }
            if (option.getValue() == null) {
                continue;
            }
            if (option.isDefaultValue.test(option)) {
                continue;
            }
            if (option.isAdvanced()) {
                commands.add("-o");
                String command = option.getFlag() +
                        "=" +
                        option.getValue().getCmdValue();
                commands.add(command);
            } else if (option.isOnlyFlag()) {
                commands.add(option.getFlag());
            } else {
                commands.add(option.getFlag());
                commands.add(option.getValue().getCmdValue());
            }
        }

        return commands;

    }

    private static final Set<String> ALLOWED_ADVANCED_OPTIONS = Set.of(
            "eepromEraseEnabled",
            "userProgramEeprom",
            "porResetDelay",
            "cpuCoreVoltage",
            "watchdogPorEnabled",
            "watchdogPrescale",
            "bslPindetectEnabled",
            "resetPinEnabled",
            "aleEnabled"

    );
}
